package com.wangc.commons.configuration;

import com.wangc.commons.dto.Route;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.annotation.EnableRabbit;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.RabbitListenerContainerFactory;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 *   @Author: wangbaojun.
 *   @Description: RabbitMQ相关配置
 *   @Date:Created in 2020/4/28 10:39.
 *   @Modified By:
 *  
 */
@Configuration
@EnableRabbit
public class RabbitMQConfig {
    @Autowired
    private AmqpAdmin amqpAdmin;

    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory,
            ProducerMessageQueue producerMessageQueue,
            ConsumerMessageQueue consumerMessageQueue) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        createProducerExchange(producerMessageQueue, rabbitTemplate);
        createConsumerExchange(consumerMessageQueue, rabbitTemplate);
        return rabbitTemplate;
    }

    /**
     * @param
     * @return void
     * @Author: 王保军
     * @Date: 2020/4/28 12.51
     * @Description: 配置交换器、队列并绑定
     */
    private void createProducerExchange(ProducerMessageQueue producerMessageQueue, RabbitTemplate rabbitTemplate) {
        //生产者配置
        producerMessageQueue.getTasks().forEach(task -> {
            if (StringUtils.equals(task.getType(), "Fanout")) {
                initFanout(task);
            } else if (StringUtils.equals(task.getType(), "Direct")) {
                initDirect(task);
            }
        });

    }

    /**
     * @param
     * @return void
     * @Author: 王保军
     * @Date: 2020/4/28 12.51
     * @Description: 配置交换器、队列并绑定
     */
    private void createConsumerExchange(ConsumerMessageQueue consumerMessageQueue, RabbitTemplate rabbitTemplate) {
        //消费方初始化
        consumerMessageQueue.getTasks().forEach(task -> {
            if (StringUtils.equals(task.getType(), "Fanout")) {
                fanoutBingExchangeAndQueue(task);
            }
            //客户端 Direct无需进行任何绑定
        });
    }

    private void fanoutBingExchangeAndQueue(Route task) {
        //完成绑定
        if (StringUtils.isNotBlank(task.getQueueName())) {
            amqpAdmin.declareQueue(new Queue(task.getQueueName(), true));
        }
        if (StringUtils.isNotBlank(task.getExchangeName())) {
            amqpAdmin.declareBinding(
                    new Binding(task.getQueueName(), Binding.DestinationType.QUEUE,
                            task.getExchangeName(),
                            task.getRoutingKey() == null ? "" : task.getRoutingKey(), null));
        }
    }

    private void initFanout(Route task) {
        amqpAdmin.declareExchange(new FanoutExchange(task.getExchangeName()));
    }

    private void initDirect(Route task) {
        if (StringUtils.isNotBlank(task.getExchangeName())) {
            amqpAdmin.declareExchange(new DirectExchange(task.getExchangeName()));
        }
        if (StringUtils.isNotBlank(task.getQueueName())) {
            amqpAdmin.declareQueue(new Queue(task.getQueueName(), true));
        }
        if (StringUtils.isNotBlank(task.getRoutingKey())) {
            amqpAdmin.declareBinding(
                    new Binding(task.getQueueName(), Binding.DestinationType.QUEUE,
                            task.getExchangeName(),
                            task.getRoutingKey(), null));
        }
    }

    @Bean
    public RabbitListenerContainerFactory rabbitListenerContainerFactory(ConnectionFactory connectionFactory){
        SimpleRabbitListenerContainerFactory listenerContainerFactory=new SimpleRabbitListenerContainerFactory();
        listenerContainerFactory.setConnectionFactory(connectionFactory);
        //--加上这句
        listenerContainerFactory.setMessageConverter(new Jackson2JsonMessageConverter());
        return listenerContainerFactory;
    }
}
